home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Games
/
Tetris
/
Source
/
Minimatrix.m
< prev
next >
Wrap
Text File
|
1975-04-26
|
6KB
|
239 lines
/*
* This is the view from which NextMatrix and TetMatrix inherit.
*
* The major data structures are.
* id *iconMatrix; Holds the id of the block that is in the current
* (row, column).
*/
#import <appkit/NXImage.h>
#import <appkit/nextstd.h>
#import <dpsclient/psops.h>
#import "Minimatrix.h"
@implementation Minimatrix
- initFrame:(const NXRect *)frameRect
{
return [self initFrame:frameRect bitmap:nil numRows:0 numCols:0];
}
- initFrame:(const NXRect *)frameRect
numRows:(int)rowsHigh numCols:(int)colsWide
{
return [self initFrame:frameRect
bitmap:nil
numRows:rowsHigh numCols:colsWide];
}
- initFrame:(const NXRect *)frameRect
bitmap:theBitmap numRows
:(int)rowsHigh numCols
:(int)colsWide
{
[super initFrame:frameRect];
numRows = rowsHigh;
numCols = colsWide;
NX_MALLOC(iconMatrix, id, numRows * numCols);
backgroundGray = NX_LTGRAY;
inset.width = inset.height = 0.0;
insetBounds = bounds;
intercell = elementSize = inset;
[self setBitmap:theBitmap];
return self;
}
/*
* Return the id of the bitmap at (row,column) if one exists, else nil.
*/
- bitmapAt:(int)row :(int)column
{
return (row < 0 || column < 0 || row >= numRows || column >= numCols) ?
nil : *(iconMatrix + row * numCols + column);
}
- displayAt:(int)row :(int)column
{
NXRect destRect;
NXSetRect(&destRect,
inset.width + column * (intercell.width + elementSize.width),
inset.height + row * (intercell.width + elementSize.width),
elementSize.width + intercell.width,
elementSize.height + intercell.height);
return [self display:&destRect :1];
}
- drawSelf:(const NXRect *)rects :(int)rectCount
{
int rowc, colc;
int rectc;
NXRect destRect;
id *iconMatrixPiece;
const NXRect *rectp;
static int bsides[] = {NX_YMIN, NX_XMAX, NX_YMAX, NX_XMIN,
NX_YMIN, NX_XMAX, NX_YMAX, NX_XMIN};
static float bgrays[] = {NX_WHITE, NX_WHITE, NX_DKGRAY, NX_DKGRAY,
NX_LTGRAY, NX_WHITE, NX_DKGRAY, NX_DKGRAY};
PSsetgray(backgroundGray);
NXRectFillList(rects, rectCount); // Clear old areas
destRect = bounds;
// Draw the insetRect around the border of the game when a Piece
// intersects with the border.
if ((inset.width || inset.height) && !NXContainsRect(&insetBounds, rects)) {
NXDrawTiledRects(&destRect, (NXRect *)0, bsides, bgrays, 8);
}
NXSetRect(&destRect, inset.width + intercell.width,
inset.height + intercell.height,
elementSize.width, elementSize.height);
iconMatrixPiece = iconMatrix;
// Redraw all of the Pieces that have changed
for (rowc = 0; rowc < numRows; rowc++) {
for (colc = 0; colc < numCols; colc++) {
if (*iconMatrixPiece) {
rectc = rectCount;
rectp = rects;
while (rectc--) {
if (NXIntersectsRect(&destRect, rectp++)) {
// If we assume the piece contains no alpha then we could use
// NX_COPY
[*iconMatrixPiece composite:NX_SOVER toPoint:&destRect.origin];
break;
}
}
}
// Add block's width + space b/w each block to get new X coord
destRect.origin.x += elementSize.width + intercell.width;
iconMatrixPiece++; // Do next column in iconMatrix
}
destRect.origin.x = inset.width + intercell.width;
// Add the block's height + intercell.height
destRect.origin.y += elementSize.height + intercell.height;
}
return self;
}
/*
* Private method.
*/
- getIntercell:(NXSize *)aSize
{
*aSize = intercell;
return self;
}
- getRect:(NXRect *)theRect for:(int)row :(int)column
{
theRect->size = elementSize; // Get block's image size
return [self point:&theRect->origin for:row :column];
}
/*
* Calculate the TetrisView coordinate given the Tetrix (row,column)
*/
- point:(NXPoint *)thePoint for:(int)row :(int)column
{
thePoint->x = inset.width + (column + 1) * intercell.width +
column * elementSize.width;
thePoint->y = inset.height + (row + 1) * intercell.height +
row * elementSize.height;
return self;
}
- setBackgroundGray:(float)gray
{
backgroundGray = gray;
return self;
}
- setBitmap:theBitmap
{
id *iconMatrixPiece;
#ifdef DEBUG
printf("setBitmap\n");
#endif
iconMatrixPiece = iconMatrix + numRows * numCols;
while (iconMatrixPiece > iconMatrix)
*--iconMatrixPiece = theBitmap;
if (theBitmap)
[theBitmap getSize:&elementSize];
return self;
}
/*
* Set the current (row, column) of the iconMatrix equal to the id of
* the block that was just dropped.
*
* There is a bug in this program. Occasionally, an invalid row
* is generated.
*
* theBitmap row, col = (24, 6)
* theBitmap row, col = (23, 6)
* theBitmap row, col = (23, 7)
* theBitmap row, col = (25, 3)
* theBitmap row, col = (698590, 3)
*/
- setBitmap:theBitmap at:(int)row :(int)column
{
if (row < numRows && row >= 0 && column < numCols && column >= 0) {
*(iconMatrix + row * numCols + column) = theBitmap;
} else {
fprintf(stderr, "Invalid row %d in Minimatrix::setBitmap\n", row);
}
return self;
}
/*
* The size of the image (TIFF or PS) we are using to build the block.
* Currently 16x16 is the image size.
*/
- setElementSize:(const NXSize *)aSize
{
elementSize = *aSize;
return self;
}
/*
* Set the number of pixels away from the border the pieces will be.
*/
- setInset:(const NXSize *)aSize
{
inset = *aSize;
insetBounds = bounds;
NXInsetRect(&insetBounds, inset.width, inset.height);
return self;
}
/*
* Set the amount of space to leave between each cell.
*/
- setIntercell:(const NXSize *)aSize
{
intercell = *aSize;
return self;
}
- free
{
NX_FREE(iconMatrix);
return [super free];
}
@end